package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.common.BaseContext;
import com.itheima.dto.OrdersDto;
import com.itheima.exception.CustomException;
import com.itheima.mapper.OrdersMapper;
import com.itheima.pojo.AddressBook;
import com.itheima.pojo.Category;
import com.itheima.pojo.Dish;
import com.itheima.pojo.OrderDetail;
import com.itheima.pojo.Orders;
import com.itheima.pojo.ShoppingCart;
import com.itheima.pojo.User;
import com.itheima.service.AddressBookService;
import com.itheima.service.OrderDetailService;
import com.itheima.service.OrdersService;
import com.itheima.service.ShoppingCartService;
import com.itheima.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {
    @Autowired
    private UserService userService;
    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private AddressBookService addressBookService;
    @Autowired
    private OrderDetailService orderDetailService;

    @Override
    @Transactional
    public void submit(Orders order) {
        /*1.保存订单表
        1.1 生成订单号，并设置Id（也用订单号）和订单号
        1.2 设置状态为2（待派送）
        1.3 设置用户id和用户name
        1.3.1 通过用户ID查询用户表
        1.4 设置下单时间和结账时间（当前时间即可）
        1.5 设置总金额
        1.5.1 根据用户id查询购物车中的所有菜品，通过单价*数量，全部加起来，计算出总金额
        1.6 设置手机号、具体地址、收货姓名
        1.6.1 根据前端传的地址ID查询地址信息，取出这三种信息
        1.7 保存订单
        2.循环保存订单明细表
        2.1 设置菜品名称（从购物车里拿）
        2.2 设置菜品图片（从购物车里拿）
        2.3 设置订单id（生成的订单号，因为订单的id就是用的订单号）
        2.4 设置菜品id、套餐id、口味信息（从购物车里拿）
        2.5 设置数量和总金额
        2.5 保存订单明细表

        3.删除购物车数据(通过用户ID删除购物车中的数据)*/

        //生成订单号
        long orderNumber = IdWorker.getId();
        //查询当前登录用户的具体信息
        User user = userService.getById(BaseContext.getCurrentId());
        //查询当前登录用户的购物车信息
        LambdaQueryWrapper<ShoppingCart> shoppingCartLQW = new LambdaQueryWrapper<>();
        shoppingCartLQW.eq(ShoppingCart::getUserId,BaseContext.getCurrentId());
        List<ShoppingCart> shoppingCartList = shoppingCartService.list(shoppingCartLQW);
        if (shoppingCartList.size() == 0){
            throw new CustomException("购物车中没有数据，无法下单");
        }
        //根据地址ID查询当前地址信息
        AddressBook addressBook = addressBookService.getById(order.getAddressBookId());
        if(addressBook == null){
            throw new CustomException("该用户没有设置地址，无法下单");
        }

        //封装订单数据
        order.setId(orderNumber);
        order.setNumber(String.valueOf(orderNumber));
        order.setStatus(2);
        order.setUserId(BaseContext.getCurrentId());
        order.setUserName(user.getName());
        order.setOrderTime(LocalDateTime.now());
        order.setCheckoutTime(LocalDateTime.now());
        BigDecimal amount = new BigDecimal(0);
        for (ShoppingCart shoppingCart : shoppingCartList) {
            amount = amount.add(shoppingCart.getAmount().multiply(new BigDecimal(shoppingCart.getNumber())));
        }
        order.setAmount(amount);
        if ("1".equals(addressBook.getSex())){
            order.setConsignee(addressBook.getConsignee()+" 先生");
        }else{
            order.setConsignee(addressBook.getConsignee()+" 女士");
        }
        order.setAddress(addressBook.getDetail());
        order.setPhone(addressBook.getPhone());
        //保存订单表
        super.save(order);

        //封装订单明细表数据
        List<OrderDetail> orderDetails = shoppingCartList.stream().map(item ->{
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setName(item.getName());
            orderDetail.setImage(item.getImage());
            orderDetail.setOrderId(orderNumber);
            orderDetail.setDishId(item.getDishId());
            orderDetail.setDishFlavor(item.getDishFlavor());
            orderDetail.setSetmealId(item.getSetmealId());
            orderDetail.setAmount(item.getAmount().multiply(new BigDecimal(item.getNumber())));
            return orderDetail;
        }).collect(Collectors.toList());
        //保存订单明细表
        orderDetailService.saveBatch(orderDetails);

        //删除当前用户的购物车
        LambdaUpdateWrapper<ShoppingCart> shoppingCartLUW = new LambdaUpdateWrapper<>();
        shoppingCartLUW.eq(ShoppingCart::getUserId,BaseContext.getCurrentId());
        shoppingCartService.remove(shoppingCartLUW);
    }

    @Override
    public Page<Orders> pageInfo(int page, int pageSize, Long number, String beginTime, String endTime) {
        Page<Orders> orderPage = new Page(page,pageSize);
        LambdaQueryWrapper<Orders> lqw = new LambdaQueryWrapper<>();
        lqw.eq(number!=null,Orders::getNumber,number);
        if (StringUtils.isNotBlank(beginTime) && StringUtils.isNotBlank(endTime)){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:ss:mm");
            Date checkOutBeginTime = null;
            Date checkOutEndTime = null;
            try {
                checkOutBeginTime = sdf.parse(beginTime);
                checkOutEndTime = sdf.parse(endTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            lqw.between(Orders::getCheckoutTime,beginTime,endTime);
        }
        super.page(orderPage, lqw);
        //查询地址表，得出用户姓名
        List<Orders> records = orderPage.getRecords();
        Set<Long> addressBookIds = new HashSet<>();
        for (Orders order : records) {
            addressBookIds.add(order.getAddressBookId());
        }
        List<AddressBook> addressBooks = addressBookService.listByIds(addressBookIds);
        Map<Long, String> categoryMap = new HashMap<>();
        for (AddressBook addressBook : addressBooks) {
            if ("1".equals(addressBook.getSex())){
                categoryMap.put(addressBook.getId(), addressBook.getConsignee() + " 先生");
            }else{
                categoryMap.put(addressBook.getId(), addressBook.getConsignee() + " 女士");
            }
        }
        for (Orders orders : records) {
            orders.setUserName(categoryMap.get(orders.getAddressBookId()));
        }
        orderPage.setRecords(records);

        return orderPage;
    }

    @Override
    public Page pageInfo(int page, int pageSize) {
        //分页查询订单数据
        Page<Orders> ordersPage = new Page<>(page,pageSize);
        LambdaQueryWrapper<Orders> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Orders::getUserId,BaseContext.getCurrentId());
        lqw.orderByDesc(Orders::getOrderTime);
        super.page(ordersPage, lqw);
        if (ordersPage.getRecords().size() <= 0) {
            return ordersPage;
        }
        //查询订单明细数据
        Set<String> orderNumbers = ordersPage.getRecords().stream().map(item -> item.getNumber()).collect(Collectors.toSet());
        LambdaQueryWrapper<OrderDetail> orderLqw = new LambdaQueryWrapper<>();
        orderLqw.in(OrderDetail::getOrderId,orderNumbers);
        List<OrderDetail> orderDetailList = orderDetailService.list(orderLqw);

        List<OrdersDto> ordersDtos = new ArrayList<>();
        //循环订单，给每一个订单设置对应的订单详情
        for (Orders order : ordersPage.getRecords()) {
            List<OrderDetail> orderDetailLists = orderDetailList.stream().filter(item -> item.getOrderId().equals(order.getId())).collect(Collectors.toList());
            //将订单信息封装到DTO中
            OrdersDto ordersDto = new OrdersDto();
            BeanUtils.copyProperties(order,ordersDto);
            ordersDto.setOrderDetails(orderDetailLists);
            ordersDto.setSumNum(orderDetailLists.size());
            ordersDtos.add(ordersDto);
        }

        Page<OrdersDto> dtoPageInfo = new Page<>();
        BeanUtils.copyProperties(ordersPage, dtoPageInfo);
        dtoPageInfo.setRecords(ordersDtos);
        return dtoPageInfo;
    }

    @Override
    @Transactional
    public void again(Orders orders) {
        //查询老订单详情信息
        LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderDetail::getOrderId, orders.getId());
        List<OrderDetail> orderDetails = orderDetailService.list(queryWrapper);

        //循环设置购物车
        ArrayList<ShoppingCart> shoppingCarts = new ArrayList<>();
        for (OrderDetail orderDetail : orderDetails) {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail, shoppingCart);
            shoppingCart.setUserId(BaseContext.getCurrentId());
            shoppingCart.setCreateTime(LocalDateTime.now());

            shoppingCarts.add(shoppingCart);
        }

        //批量添加数据到购物车
        shoppingCartService.saveBatch(shoppingCarts);
    }
}
